package com.chat.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chat.admin.config.JwtProperties;
import com.chat.admin.domain.DTO.LoginAdminDTO;
import com.chat.admin.domain.DTO.RefreshTokenDTO;
import com.chat.admin.domain.VO.LoginAdminVO;
import com.chat.admin.domain.VO.RefreshTokenVO;
import com.chat.admin.mapper.LoginMapper;
import com.chat.admin.service.IRoleService;
import com.chat.admin.service.LoginService;
import com.chat.admin.utils.JwtTool;
import com.chat.admin.utils.RedisUtil;
import com.chat.common.common.constant.MessageConstant;
import com.chat.common.common.constant.RedisKeyConstant;
import com.chat.common.common.exception.RoutineException;
import com.chat.common.entity.Admin;
import com.chat.common.entity.Role;
import com.chat.common.vo.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class LoginServiceImpl extends ServiceImpl<LoginMapper, Admin> implements LoginService {

    @Autowired
    private PasswordEncoder passwordEncoder;
    //jwt工具
    @Autowired
    private JwtTool jwtTool;
    //jwt配置
    @Autowired
    private JwtProperties jwtProperties;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    IRoleService iRoleService;

    @Override
    public R<LoginAdminVO> login(LoginAdminDTO loginAdminDTO) {
        Admin admin = baseMapper
                .selectOne(
                        new LambdaQueryWrapper<Admin>()
                                .eq(Admin::getUsername, loginAdminDTO.getUsername())
                );
        if (admin==null){
            //判断账号是否存在
            throw new RoutineException(MessageConstant.ACCOUNT_NOT_FOUND);
        } else if(admin.getState() != 1){
            //判断账号是否被锁定
            throw new RoutineException(MessageConstant.ACCOUNT_LOCKED);
        } else if(passwordEncoder.matches(loginAdminDTO.getPassword(), admin.getPassword())){
            //判断密码是否错误
            throw new RoutineException(MessageConstant.PASSWORD_ERROR);
        } else if(!iRoleService.isRoleValid(admin.getRoleId())) {
            throw new RoutineException("当前角色已失效");
        } else {
            //判断是否登录
            if(redisUtil.hasKey(RedisKeyConstant.ADMIN_ACCOUNT_ForToken + admin.getId())){
                //是就清除
                redisUtil.delete(RedisKeyConstant.ADMIN_ACCOUNT_ForToken + admin.getId());
            }
            //创建token
            String accessToken = jwtTool.createToken(admin.getId(),jwtProperties.getAccessTokenTTL());
            String refreshToken = jwtTool.createToken(admin.getId(),jwtProperties.getRefreshTokenTTL());
//            Duration ttl = Duration.ofMinutes(1);
//            String accessToken = jwtTool.createToken(admin.getId(),ttl);
//            String refreshToken = jwtTool.createToken(admin.getId(),ttl);
            LoginAdminVO loginAdminVO = new LoginAdminVO();
            BeanUtil.copyProperties(admin,loginAdminVO);
            loginAdminVO.setAccessToken(accessToken);
            loginAdminVO.setRefreshToken(refreshToken);
            //获取角色列表
            List<Role> roles = iRoleService.getStateRoles();
            if (!roles.isEmpty()) {
                //设置权限列表
                //TODO 使用硬编码，后期可能会改
                Role oneRole = roles.get(Math.toIntExact(admin.getId()-1));
                List<String> role = List.of(oneRole.getName());
                loginAdminVO.setRoles(role);
            }
            // 获取当前时间
            LocalDateTime now = LocalDateTime.now();
            // 获取当前时间一个小时后
            LocalDateTime oneHourLater = now.plusHours(1);
            //LocalDateTime oneHourLater =  now.plusMinutes(1);
            // 定义日期时间格式
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
            // 格式化当前时间
            String formattedNow = oneHourLater.format(formatter);
            // 格式化一个小时后的时间
            loginAdminVO.setExpires(formattedNow);
            //把token存入redis
            //redisUtil.setEx(RedisKeyConstant.TOKEN_ADMIN + refreshToken, admin.getId(), 12, TimeUnit.HOURS);
            //TODO 记得改
            redisUtil.setEx(RedisKeyConstant.ADMIN_ACCOUNT_ForToken + admin.getId(), now.format(formatter), 12, TimeUnit.HOURS);
            return R.succeed(loginAdminVO);
        }
    }

    @Override
    public R<RefreshTokenVO> refreshToken(RefreshTokenDTO refreshToken) {
        Long userID =  jwtTool.parseToken(refreshToken.getRefreshToken());
        String accessToken = jwtTool.createToken(userID,jwtProperties.getAccessTokenTTL());
        // 获取当前时间
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime oneHourLater = now.plusHours(1);
        //LocalDateTime oneHourLater =  now.plusMinutes(1);
        // 定义日期时间格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
        // 格式化当前时间
        String formattedNow = oneHourLater.format(formatter);
        RefreshTokenVO refreshTokenVO = new RefreshTokenVO();
        refreshTokenVO.setAccessToken(accessToken);
        refreshTokenVO.setRefreshToken(refreshToken.getRefreshToken());
        refreshTokenVO.setExpires(formattedNow);
        return R.succeed(refreshTokenVO);
    }
}
